#pragma once

// Copyright (c) 2010 Manuel Peinado Gallego <manuel.peinado@gmail.com>
// Distributed under the MIT license

// Plane.h : interface of the Plane class
//

#include <alg3d/alg3d.h>

struct Plane
{
    Plane(const gx::Vec3 & n=gx::K, const gx::Vec3 & p=gx::zero) 
        : n(n), D(-n.dot(p))
    {
    }
    gx::Vec3 n;
    double D;

    double signed_dist(const gx::Vec3 & other_pnt) const 
    {   
        return n.dot(other_pnt) + D; 
    }

    gx::Vec3 project(const gx::Vec3 & p)
    {
        double dist = signed_dist(p);
        return gx::Vec3(p.x - n.x * dist, p.y - n.y * dist, p.z - n.z * dist);
    }
};

bool rayPlaneIntersection(const gx::Vec3 & rayO, const gx::Vec3 & rayDir,  
    const Plane & plane, gx::Vec3 & result);